﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Data;
using System.IO;

namespace Helper_Ji
{
    public class Helper_Data
    {
        public static class XmlHelper
        {
            public static XmlElement AppendChildElement(XmlNode node, string name)
            {
                XmlElement newChild = ((node is XmlDocument) ? ((XmlDocument)node) : node.OwnerDocument).CreateElement(name, node.NamespaceURI);
                node.AppendChild(newChild);
                return newChild;
            }

            public static void CreateXmlReaderForSipMessage(string msgBody, object context, ReadXmlContentDelegate readContentCallback, string rootNode)
            {
                bool flag = (rootNode != null) && (rootNode.Length > 0);
                XmlTextReader reader = new XmlTextReader(msgBody, XmlNodeType.Document, null);
                if (flag)
                {
                    reader.ReadStartElement(rootNode);
                }
                if (readContentCallback != null)
                {
                    readContentCallback(reader, context);
                }
            }

            public static void CreateXmlReaderForSipResponse(string msgBody, object context, ReadXmlContentDelegate readContentCallback)
            {
                CreateXmlReaderForSipMessage(msgBody, context, readContentCallback, "results");
            }

            public static void CreateXmlWriterForSipMessage(TextWriter tw, object context, WriteXmlContentDelegate writeContentCallback, string rootNode)
            {
                bool flag = (rootNode != null) && (rootNode.Length > 0);
                XmlTextWriter writer = new XmlTextWriter(tw);
                if (flag)
                {
                    writer.WriteStartElement(rootNode);
                }
                if (writeContentCallback != null)
                {
                    writeContentCallback(writer, context);
                }
                if (flag)
                {
                    writer.WriteEndElement();
                }
                writer.Flush();
                writer.Close();
            }

            public static void CreateXmlWriterForSipRequest(TextWriter tw, object context, WriteXmlContentDelegate writeContentCallback)
            {
                CreateXmlWriterForSipMessage(tw, context, writeContentCallback, "args");
            }

            public static XmlNode GetXmlNodeOfReceiveMessage(string msgBody, string nodeName)
            {
                return GetXmlNodeOfReceiveMessage(msgBody, nodeName, null);
            }

            public static XmlNode GetXmlNodeOfReceiveMessage(string msgBody, string nodeName, string rootName)
            {
                XmlDocument document = new XmlDocument();
                document.LoadXml(msgBody);
                XmlNode documentElement = document.DocumentElement;
                if (!string.IsNullOrEmpty(rootName) && (rootName != documentElement.Name))
                {
                    throw new ApplicationException("rootName != root.Name");
                }
                return documentElement.SelectSingleNode(nodeName);
            }

            public static bool LoadXmlDocSafely(string filepath, XmlDocument doc, object syncObj)
            {
                lock (syncObj)
                {
                    try
                    {
                        doc.Load(filepath);
                    }
                    catch
                    {
                        return false;
                    }
                    return true;
                }
            }

            public static XmlNode MakeSureChildNodeExists(XmlNode node, string name)
            {
                XmlDocument doc = (node is XmlDocument) ? ((XmlDocument)node) : node.OwnerDocument;
                return MakeSureChildNodeExists(node, name, doc);
            }

            private static XmlNode MakeSureChildNodeExists(XmlNode node, string name, XmlDocument doc)
            {
                XmlNode newChild = node.SelectSingleNode(name);
                if (newChild == null)
                {
                    if ((node == doc) && doc.HasChildNodes)
                    {
                        doc.RemoveAll();
                    }
                    newChild = doc.CreateElement(name, node.NamespaceURI);
                    node.AppendChild(newChild);
                }
                return newChild;
            }

            public static XmlNode MakeSureChildPathExists(XmlNode node, string xpath)
            {
                if (string.IsNullOrEmpty(xpath))
                {
                    throw new ArgumentException("Invalid xpath - <empty>");
                }
                XmlDocument doc = (node is XmlDocument) ? ((XmlDocument)node) : node.OwnerDocument;
                XmlNode node2 = null;
                int startIndex = 0;
                while (startIndex < xpath.Length)
                {
                    int index = xpath.IndexOf('/', startIndex);
                    if (index < 0)
                    {
                        index = xpath.Length;
                    }
                    string name = xpath.Substring(startIndex, index - startIndex);
                    if (name.Length <= 0)
                    {
                        throw new ArgumentException("Invalid xpath - " + xpath);
                    }
                    startIndex = index + 1;
                    node2 = MakeSureChildNodeExists(node, name, doc);
                    node = node2;
                }
                return node2;
            }

            public static XmlNode MakeSureXmlNodeExists(XmlDocument doc, string path)
            {
                XmlNode node = doc;
                while (path.Length > 0)
                {
                    int index = path.IndexOf('/');
                    if (index == 0)
                    {
                        throw new Exception("Invalid path!");
                    }
                    if (index < 0)
                    {
                        return MakeSureChildNodeExists(node, path);
                    }
                    string name = path.Substring(0, index);
                    node = MakeSureChildNodeExists(node, name);
                    path = path.Substring(index + 1);
                }
                return null;
            }

            public static bool? ReadXmlAttributeBoolean(XmlNode node, string attrName)
            {
                string str = ReadXmlAttributeString(node, attrName).Trim();
                bool? nullable = null;
                if (str.Length == 1)
                {
                    return new bool?(str == "1");
                }
                if (str.Length > 0)
                {
                    nullable = new bool?(Convert.ToBoolean(str));
                }
                return nullable;
            }

            public static bool ReadXmlAttributeBoolean(XmlNode node, string attrName, bool defaultVal)
            {
                bool? nullable2 = ReadXmlAttributeBoolean(node, attrName);
                if (!nullable2.HasValue)
                {
                    return defaultVal;
                }
                return nullable2.GetValueOrDefault();
            }

            public static DateTime? ReadXmlAttributeDateTime(XmlNode node, string attrName)
            {
                string str = ReadXmlAttributeString(node, attrName).Trim();
                DateTime? nullable = null;
                if (str.Length > 0)
                {
                    nullable = new DateTime?(Convert.ToDateTime(str));
                }
                return nullable;
            }

            public static DateTime ReadXmlAttributeDateTime(XmlNode node, string attrName, DateTime defaultVal)
            {
                DateTime? nullable2 = ReadXmlAttributeDateTime(node, attrName);
                if (!nullable2.HasValue)
                {
                    return defaultVal;
                }
                return nullable2.GetValueOrDefault();
            }

            public static T ReadXmlAttributeEnum<T>(XmlNode node, string attrName, T defaultVal)
            {
                int? nullable = ReadXmlAttributeInt32(node, attrName);
                if (!nullable.HasValue || !nullable.HasValue)
                {
                    return defaultVal;
                }
                try
                {
                    return (T)Enum.ToObject(typeof(T), nullable.Value);
                }
                catch
                {
                    return defaultVal;
                }
            }

            public static int? ReadXmlAttributeInt32(XmlNode node, string attrName)
            {
                int num;
                if (int.TryParse(ReadXmlAttributeString(node, attrName).Trim(), out num))
                {
                    return new int?(num);
                }
                return null;
            }

            public static int ReadXmlAttributeInt32(XmlNode node, string attrName, int defaultVal)
            {
                int? nullable2 = ReadXmlAttributeInt32(node, attrName);
                if (!nullable2.HasValue)
                {
                    return defaultVal;
                }
                return nullable2.GetValueOrDefault();
            }

            public static long? ReadXmlAttributeInt64(XmlNode node, string attrName)
            {
                long num;
                if (long.TryParse(ReadXmlAttributeString(node, attrName).Trim(), out num))
                {
                    return new long?(num);
                }
                return null;
            }

            public static long ReadXmlAttributeInt64(XmlNode node, string attrName, long defaultVal)
            {
                long? nullable2 = ReadXmlAttributeInt64(node, attrName);
                if (!nullable2.HasValue)
                {
                    return defaultVal;
                }
                return nullable2.GetValueOrDefault();
            }

            public static string ReadXmlAttributeString(XmlNode node, string attrName)
            {
                return ReadXmlAttributeString(node, attrName, false);
            }

            public static string ReadXmlAttributeString(XmlNode node, string attrName, bool required)
            {
                XmlAttribute attribute = node.Attributes[attrName];
                if (required)
                {
                    if ((attribute == null) || (attribute.Value.Length <= 0))
                    {
                        throw new ApplicationException(string.Format("Attribute - {0} is missed!", attrName));
                    }
                    return attribute.Value;
                }
                if (attribute != null)
                {
                    return attribute.Value;
                }
                return string.Empty;
            }

            public static bool SaveXmlDocSafely(XmlDocument doc, string filepath, object syncObj)
            {
                lock (syncObj)
                {
                    try
                    {
                        doc.Save(filepath);
                    }
                    catch
                    {
                        return false;
                    }
                    return true;
                }
            }

            public static void SetNodeAttribute(XmlNode node, string attrName, string attrVal)
            {
                XmlDocument document = (node is XmlDocument) ? ((XmlDocument)node) : node.OwnerDocument;
                XmlAttribute attribute = node.Attributes[attrName];
                if (attribute == null)
                {
                    attribute = node.Attributes.Append(document.CreateAttribute(attrName));
                }
                attribute.Value = attrVal;
            }

            public static void SetNodeAttributeBool(XmlNode node, string attrName, bool attrVal)
            {
                SetNodeAttribute(node, attrName, attrVal ? "1" : "0");
            }

            public static void SetNodeAttributeInt32(XmlNode node, string attrName, int attrVal)
            {
                SetNodeAttribute(node, attrName, attrVal.ToString());
            }

            public static void WriteAttributeStringNotEmpty(XmlWriter writer, string attrName, string attrVal)
            {
                if (!string.IsNullOrEmpty(attrVal))
                {
                    writer.WriteAttributeString(attrName, attrVal);
                }
            }

            public delegate void ReadXmlContentDelegate(XmlReader reader, object context);

            public delegate void WriteXmlContentDelegate(XmlWriter writer, object context);
      
        
        
        }
       
        public class XmlParser
        {
            private XmlDocument doc;

            public XmlParser(string dataStr)
            {
                this.doc = new XmlDocument();
                try
                {
                    this.doc.LoadXml(dataStr);
                }
                catch (Exception e)
                {
                    throw e;
                }
            }

            public XmlDocument Doc
            {
                get { return this.doc; }
            }

            /// <summary>
            /// 读取指定结点信息
            /// </summary>
            /// <param name="sectionName">父节点</param>
            /// <param name="nodename">子节点名称</param>
            /// <returns>节点值</returns>
            public string GetAppsetting(string sectionName, string nodename)
            {
                string result = string.Empty;
                XmlNodeList nodelist = null;
                try
                {
                    nodelist = this.doc.SelectSingleNode(sectionName).ChildNodes;
                }
                catch
                {
                    result = "Cannot find the value of" + sectionName + "in ConfigFile!";
                }
                foreach (XmlNode node in nodelist)
                {
                    if (node.Name == nodename)
                    {
                        result = node.InnerText;
                        break;
                    }
                    else
                    {
                        result = "Cannot find the value of" + nodename + "in ConfigFile!";
                    }
                }
                return result;
            }

            /// <summary>
            /// 返回指定结点的值
            /// </summary>
            /// <param name="xmlPathNode">路径（xpath）</param>
            /// <returns>如果XPATH找不到，返回NULL</returns>
            public string GetNodeValue(string xmlPathNode)
            {
                string nodeValue = string.Empty;
                if (this.doc.SelectSingleNode(xmlPathNode) != null)
                {
                    nodeValue = this.doc.SelectSingleNode(xmlPathNode).InnerText;
                }
                else
                {
                    nodeValue = string.Empty;
                }
                return nodeValue;
            }

            public string GetNodeAttribute(string xmlPath, string attribName)
            {
                XmlNode node = null;
                if (this.doc.SelectSingleNode(xmlPath) != null)
                {
                    node = this.doc.SelectSingleNode(xmlPath);
                    XmlAttribute attrib = node.Attributes[attribName];
                    if (attrib != null)
                        return attrib.Value;
                    else
                        return string.Empty;
                }
                return string.Empty;
            }

            // 查找指定节点的数据 返回DataView
            public DataView GetDataView(string xmlPathNode)
            {
                DataSet dst = new DataSet();
                StringReader read = new StringReader(this.doc.SelectSingleNode(xmlPathNode).OuterXml);
                dst.ReadXml(read);
                return dst.Tables[0].DefaultView;
            }

            public DataTable GetDataTable(string xmlPathNode)
            {
                if (this.doc.SelectSingleNode(xmlPathNode) == null)
                    return null;
                DataSet dst = new DataSet();
                StringReader read = new StringReader(this.doc.SelectSingleNode(xmlPathNode).OuterXml);
                dst.ReadXml(read);
                if (dst.Tables.Count > 0)
                    return dst.Tables[0];
                else
                    return null;
            }

            public DataSet GetDataSet(string xmlPathNode)
            {
                DataSet dst = new DataSet();
                StringReader read = new StringReader(this.doc.SelectSingleNode(xmlPathNode).OuterXml);
                dst.ReadXml(read);
                return dst;
            }

            /// <summary>
            /// 更新指定节点的内容
            /// </summary>
            /// <param name="xmlPathNode">节点</param>
            /// <param name="content">内容</param>
            public void EditNode(string xmlPathNode, string content)
            {
                this.doc.SelectSingleNode(xmlPathNode).InnerText = content;
            }

            /// <summary>
            /// 删除指定节点
            /// </summary>
            /// <param name="node">节点</param>
            public void Delete(string node)
            {
                string mainNode = node.Substring(0, node.LastIndexOf("/"));
                this.doc.SelectSingleNode(mainNode).RemoveChild(this.doc.SelectSingleNode(node));
            }

            /// <summary>
            /// 插入一个节点和此节点的一子节点。
            /// </summary>
            /// <param name="mainNode">根节点</param>
            /// <param name="childNode">子节点</param>
            /// <param name="element">元素名</param>
            /// <param name="content">值</param>
            public void InsertNode(string mainNode, string childNode, string element, string content)
            {
                XmlNode objRootNode = this.doc.SelectSingleNode(mainNode);
                XmlElement objChildNode = this.doc.CreateElement(childNode);
                objRootNode.AppendChild(objChildNode);
                XmlElement objElement = this.doc.CreateElement(element);
                objElement.InnerText = content;
                objChildNode.AppendChild(objElement);
            }

            /// <summary>
            /// 插入一节点 包括一个属性
            /// </summary>
            /// <param name="mainNode">根节点</param>
            /// <param name="element">子节点</param>
            /// <param name="attrib">属性名</param>
            /// <param name="attribContent">属性内容</param>
            /// <param name="content">子节点内容</param>
            public void InsertElement(string mainNode, string element, string attrib, string attribContent, string content)
            {
                XmlNode objNode = this.doc.SelectSingleNode(mainNode);
                XmlElement objElement = this.doc.CreateElement(element);
                objElement.SetAttribute(attrib, attribContent);
                objElement.InnerText = content;
                objNode.AppendChild(objElement);
            }

            // 插入一个节点，包括两个属性
            public void InsertElement(string mainNode, string element, string attrib1, string attrib2, string attribContent1, string attribContent2, string content)
            {
                XmlNode objNode = this.doc.SelectSingleNode(mainNode);
                XmlElement objElement = this.doc.CreateElement(element);
                objElement.SetAttribute(attrib1, attribContent1);
                objElement.SetAttribute(attrib2, attribContent2);
                objElement.InnerText = content;
                objNode.AppendChild(objElement);
            }

            // 插入一节点不带属性
            public void InsertElement(string mainNode, string element, string content)
            {
                XmlNode objNode = this.doc.SelectSingleNode(mainNode);
                XmlElement objElement = this.doc.CreateElement(element);
                objElement.InnerText = content;
                objNode.AppendChild(objElement);
            }

            public void Dispose()
            {
                this.doc = null;
            }
        }
    }
}
